import os
import pandas as pd

def sync_remarks(
    input_dir="input",
    output_dir="output",
    key_columns=None,
    remark_column="备注",
    main_file_name=None,
    sub_file_name=None,
    output_file=None,
    save_func=None,
):
    """
    在 input_dir 中读取两个文件（主文件 main_file_name，副文件 sub_file_name；若未指定则使用前两个文件），
    根据 key_columns（列表或逗号分隔字符串）进行匹配，把副文件中 remark_column 的值同步到主文件的最后一列备注。
    返回输出文件绝对路径。
    """
    os.makedirs(output_dir, exist_ok=True)

    # 获取文件列表
    files = [f for f in os.listdir(input_dir) if f.lower().endswith((".xlsx", ".xls"))]
    if not files:
        raise ValueError("未找到 Excel 文件，请重新上传！")

    # 选择主/副文件
    if main_file_name is None or sub_file_name is None:
        if len(files) < 2:
            raise ValueError("需要至少两个文件用于同步备注（主文件与副文件）")
        main_file_name = main_file_name or files[0]
        sub_file_name = sub_file_name or files[1]

    main_path = os.path.join(input_dir, main_file_name)
    sub_path = os.path.join(input_dir, sub_file_name)

    if not os.path.exists(main_path):
        raise FileNotFoundError(f"主文件不存在：{main_path}")
    if not os.path.exists(sub_path):
        raise FileNotFoundError(f"副文件不存在：{sub_path}")

    # 解析 key_columns
    if key_columns is None:
        key_cols = ["ID"]
    elif isinstance(key_columns, str):
        key_cols = [c.strip() for c in key_columns.split(",") if c.strip()]
        if not key_cols:
            key_cols = ["ID"]
    elif isinstance(key_columns, (list, tuple)):
        key_cols = [str(c).strip() for c in key_columns if str(c).strip()]
        if not key_cols:
            key_cols = ["ID"]
    else:
        raise ValueError("key_columns 必须为字符串或列表")

    # 读取 Excel（第一个 sheet），保留为 str
    try:
        main_df = pd.read_excel(main_path, dtype=str)
        sub_df = pd.read_excel(sub_path, dtype=str)
    except Exception as e:
        raise ValueError(f"读取 Excel 失败：{e}")

    # 检查关键列是否存在
    for kc in key_cols:
        if kc not in main_df.columns:
            raise ValueError(f"主文件中缺少对比列：{kc}")
        if kc not in sub_df.columns:
            raise ValueError(f"副文件中缺少对比列：{kc}")

    # 检查备注列在副文件是否存在
    if remark_column not in sub_df.columns:
        raise ValueError(f"副文件中未找到备注列：{remark_column}")

    # 准备副文件的映射：key tuple -> 备注值
    def make_key_tuple(row, cols):
        return tuple(
            "" if pd.isna(row.get(c, "")) else str(row.get(c, "")).strip() for c in cols
        )

    # 用副文件构建查找表（若副文件有重复 key，后出现的覆盖前面）
    lookup = {}
    for _, r in sub_df.iterrows():
        key = make_key_tuple(r, key_cols)
        val = r.get(remark_column, "")
        lookup[key] = "" if pd.isna(val) else str(val)

    # 如果主文件没有备注列，新增（放到最后）
    if "备注" not in main_df.columns:
        main_df["备注"] = ""

    # 把副文件备注同步到主文件（匹配 key）
    for idx, row in main_df.iterrows():
        key = make_key_tuple(row, key_cols)
        if key in lookup:
            main_df.at[idx, "备注"] = lookup[key]

    # 输出文件名
    if output_file:
        out_name = output_file
    else:
        out_name = f"sync_remarks_{os.path.splitext(main_file_name)[0]}.xlsx"

    out_path = os.path.join(output_dir, out_name)

    # 保存（支持外部 save_func）
    try:
        if save_func:
            # 将 DataFrame 写入临时 Excel 再用 save_func 保存，或直接用 pandas ExcelWriter
            with pd.ExcelWriter(out_path, engine="openpyxl") as writer:
                main_df.to_excel(writer, index=False)
            # 如果 save_func 需要 openpyxl Workbook，可另行实现；这里我们先尝试写入并返回路径
            return out_path
        else:
            with pd.ExcelWriter(out_path, engine="openpyxl") as writer:
                main_df.to_excel(writer, index=False)
    except Exception as e:
        raise ValueError(f"保存结果失败：{e}")

    return out_path
